package org.datascooter.utils;

import java.util.HashMap;
import java.util.Map;

public class ProgressTask {

	private String name, description;
	private int length = 1;
	private int position = 0;
	private Map<String, ProgressTask> childMap = new HashMap<String, ProgressTask>();
	private ProgressTask parent;
	private long start = 0;
	private long finish = 0;
	private long lastPiont = -1;
	private long estimate = 0;

	public ProgressTask(String name, String description) {
		this.parent = null;
		this.name = name;
		this.description = description;
	}

	public ProgressTask(ProgressTask parent, String name, String description, int length) {
		this.parent = parent;
		this.name = name;
		this.description = description;
		this.length = length;
	}

	public ProgressTask createChild(String name, String description, int length) {
		ProgressTask task = new ProgressTask(this, name, description, length);
		childMap.put(name, task);
		return task;
	}

	public ProgressTask getChild(String name) {
		return childMap.get(name);
	}

	public ProgressTask getChild(String... nameArray) {
		ProgressTask progressTask = getChild(nameArray[0]);
		if (progressTask == null) {
			return null;
		}
		for (int a = 1; a < nameArray.length; a++) {
			progressTask = progressTask.getChild(nameArray[a]);
			if (progressTask == null) {
				return null;
			}
		}
		return progressTask;
	}

	public void start() {
		start = System.currentTimeMillis();
	}

	public void work() {
		if (position < length) {
			++position;
			calculateTime();
			if (position >= length && parent != null) {
				parent.work();
				finish = System.currentTimeMillis();
			}
		}
	}

	public void work(int workCount) {
		if (position < length) {
			position += workCount;
			calculateTime();
			if (position >= length && parent != null) {
				parent.work();
				finish = System.currentTimeMillis();
			}
		}
	}

	private void calculateTime() {
		if (position > 0 && position < length) {
			if (lastPiont < 0) {
				lastPiont = start;
			}
			estimate = (System.currentTimeMillis() - lastPiont) * (length - position);
			lastPiont = System.currentTimeMillis();
		} else {
			estimate = 0;
		}
	}

	public int getLength() {
		return length;
	}

	public int getPosition() {
		return position;
	}

	public ProgressTask getParent() {
		return parent;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public long getEstimate() {
		if (finish > 0) {
			return 0;
		}
		return estimate;
	}

	public long getDuration() {
		if (finish > 0) {
			return finish - start;
		}
		return System.currentTimeMillis() - start;
	}

	public long getFinish() {
		return finish;
	}
}
